package com.sinping.qh.service.admin.impl;

import com.sinping.qh.api.support.*;
import com.sinping.qh.domain.common.UnitDomain;
import com.sinping.qh.domain.lab.LaboratoryDomain;
import com.sinping.qh.domain.user.UserInfo;
import com.sinping.qh.domain.user.UserLaboratory;
import com.sinping.qh.dto.admin.ApiUnitDto;
import com.sinping.qh.dto.auth.UserSessionDTO;
import com.sinping.qh.query.lab.UnitQuery;
import com.sinping.qh.repository.mongo.UnitRepository;
import com.sinping.qh.repository.mongo.lab.LaboratoryRepository;
import com.sinping.qh.repository.mongo.user.UserInfoRepository;
import com.sinping.qh.repository.mongo.user.UserLaboratoryRepository;
import com.sinping.qh.service.MongoManager;
import com.sinping.qh.service.admin.IUnitService;
import com.sinping.qh.service.auth.ISessionService;
import com.sinping.qh.service.common.CommonDbConst;
import com.sinping.qh.utils.mapper.BeanMapper;
import com.sinping.qh.utils.mapper.JsonMapper;
import com.sinping.qh.utils.misc.IdGenerator;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 单位接口实现类
 *
 * @author Tiansx
 * @create 2018-05-29 11:21
 **/
@Service
public class UnitServiceImpl implements IUnitService {
    @Autowired
    private UnitRepository unitRepository;
    @Autowired
    private UserInfoRepository userInfoRepository;
    @Autowired
    private UserLaboratoryRepository userLaboratoryRepository;
    @Autowired
    private LaboratoryRepository laboratoryRepository;
    @Qualifier("sessionServiceRedisImpl")
    @Autowired
    private ISessionService iSessionService;
    @Autowired
    MongoManager mongoManager;
    private final static Logger logger = LoggerFactory.getLogger(UnitServiceImpl.class);

    @Override
    public ResDto addUnit(HttpServletRequest httpRequest, ApiUnitDto apiUnitDTO) {

        try {

            /**
             * 获取当前用户id
             */
            String token = httpRequest.getHeader(Const.TOKEN_NAME);
            UserSessionDTO userSessionDTO = iSessionService.getSessionByToken(token);
            //验证参数
            if (StringUtils.isBlank(userSessionDTO.getId())) {

                return new ResDto(Const.SERVER_ERROR, "获取用户id失败");
            }
            //设置创建人id
            apiUnitDTO.setCreateUserId(userSessionDTO.getId());
            UserInfo userOne = userInfoRepository.findOne(apiUnitDTO.getCreateUserId());
            if (userOne == null) {
                return new ResDto(Const.SERVER_ERROR, "创建人不存在");
            }
            if (StringUtils.isNotBlank(apiUnitDTO.getUnitName())) {
                List<UnitDomain> unitDomainExistList = unitRepository.findAllByUnitNameAndStatus(apiUnitDTO.getUnitName(), CommonDbConst.DB_DELETE_NORMAL);
                for (UnitDomain unitDomainOne : unitDomainExistList) {
                    if (unitDomainOne != null) {
                        if (CommonDbConst.DB_DELETE_NORMAL.equals(unitDomainOne.getStatus())) {
                            return new ResDto(Const.SERVER_ERROR, "单位名称已存在");
                        }

                    }
                }
            }

            UnitDomain unitDomain = BeanMapper.map(apiUnitDTO, UnitDomain.class);
            unitDomain.setId(IdGenerator.uuid2());

            //0: 否 1:是
            unitDomain.setIsAutomatic(CommonDbConst.IS_AUTOMATIC_NO);
            //0:正常 1：逻辑删除
            unitDomain.setStatus(CommonDbConst.DB_DELETE_NORMAL);
            unitDomain.setUpdateUserId(apiUnitDTO.getCreateUserId());
            unitDomain.setGmtCreated(new Date());
            unitDomain.setGmtModified(new Date());

            UnitDomain save = unitRepository.save(unitDomain);
            if (save == null) {
                return new ResDto(Const.SERVER_ERROR, "单位记录生成失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("生成单位信息异常：{}", e);
            return new ResDto(Const.SERVER_ERROR, "单位记录生成失败");
        }
        return new ResDto(Const.SUCCESS, "单位记录生成成功");

    }

    @Override
    public ResDto updateUnit(HttpServletRequest httpRequest, ApiUnitDto apiunitDTO) {
        /**
         * 获取当前用户id
         */
        String token = httpRequest.getHeader(Const.TOKEN_NAME);
        UserSessionDTO userSessionDTO = iSessionService.getSessionByToken(token);
        //验证参数
        if (StringUtils.isBlank(userSessionDTO.getId())) {

            return new ResDto(Const.SERVER_ERROR, "获取用户id失败");
        }
        //设置修改人id
        apiunitDTO.setUpdateUserId(userSessionDTO.getId());

        UnitDomain unitDomainOne = null;
        if (StringUtils.isNotBlank(apiunitDTO.getId())) {
            unitDomainOne = unitRepository.findOne(apiunitDTO.getId());
            if (unitDomainOne == null) {
                return new ResDto(Const.SERVER_ERROR, "单位不存在");
            }
            if (CommonDbConst.DB_DELETE_LOGICAL.equals(unitDomainOne.getStatus())) {
                return new ResDto(Const.SERVER_ERROR, "单位已被删除");
            }
        }
        if (CommonDbConst.UNIT_TYPE_XIAO.equals(apiunitDTO.getUnitType())
                && CommonDbConst.UNIT_TYPE_YUAN.equals(unitDomainOne.getUnitType())
                && CommonDbConst.IS_AUTOMATIC_YES.equals(unitDomainOne.getIsAutomatic())) {
            return new ResDto(Const.SERVER_ERROR, "该院系已设置自动审核，请先取消自动审核关系");
        }


        if (StringUtils.isNotBlank(apiunitDTO.getUpdateUserId())) {
            UserInfo one = userInfoRepository.findOne(apiunitDTO.getUpdateUserId());
            if (one == null) {
                return new ResDto(Const.SERVER_ERROR, "更新人不存在");
            }
        }

        if (StringUtils.isNotBlank(apiunitDTO.getUnitName())) {
            List<UnitDomain> unitDomainExistList = unitRepository.findAllByUnitNameAndStatus(apiunitDTO.getUnitName(), CommonDbConst.DB_DELETE_NORMAL);
            for (UnitDomain unitDomainExist : unitDomainExistList) {
                if (unitDomainExist != null) {
                    if (CommonDbConst.DB_DELETE_NORMAL.equals(unitDomainExist.getStatus()) && !unitDomainExist.getId().equals(apiunitDTO.getId())) {
                        return new ResDto(Const.SERVER_ERROR, "单位名称已存在");
                    }
                }
            }
        }

        UnitDomain unitDomain = BeanMapper.map(unitDomainOne, UnitDomain.class);
        unitDomain.setUnitName(apiunitDTO.getUnitName());
        unitDomain.setUpdateUserId(apiunitDTO.getUpdateUserId());
        unitDomain.setUnitType(apiunitDTO.getUnitType());
        unitDomain.setGmtModified(new Date());


        try {
            UnitDomain save = unitRepository.save(unitDomain);
            if (save == null) {
                return new ResDto(Const.SERVER_ERROR, "单位记录修改失败");
            }
            //更新用户负责表
            List<UserLaboratory> allUserByManagerUnitId = userLaboratoryRepository.findAllByManagerUnitId(unitDomain.getId());
            for (UserLaboratory userLaboratory : allUserByManagerUnitId) {
                userLaboratory.setManagerUnitName(apiunitDTO.getUnitName());
            }
            userLaboratoryRepository.save(allUserByManagerUnitId);
            //更新用户信息表
            List<UserInfo> allUserByUnitId = userInfoRepository.findAllByUnitId(unitDomain.getId());
            for (UserInfo userInfo : allUserByUnitId) {
                userInfo.setUnitName(apiunitDTO.getUnitName());
            }
            userInfoRepository.save(allUserByUnitId);
            //更新实验室表
            List<LaboratoryDomain> allLabByUnitId = laboratoryRepository.findAllByUnitId(unitDomain.getId());
            for (LaboratoryDomain laboratoryDomain : allLabByUnitId) {
                laboratoryDomain.setUnitName(apiunitDTO.getUnitName());
            }
            laboratoryRepository.save(allLabByUnitId);

        } catch (Exception e) {
            e.printStackTrace();
            logger.error("修改单位信息异常：{}", e);
            return new ResDto(Const.SERVER_ERROR, "单位记录修改失败");
        }


        return new ResDto(Const.SUCCESS, "单位信息修改成功");
    }

    @Override
    public ResDto getUnitDetail(String id) {
        UnitDomain unitDomainOne = null;
        if (StringUtils.isNotBlank(id)) {
            unitDomainOne = unitRepository.findOne(id);
            if (unitDomainOne == null) {
                return new ResDto(Const.SERVER_ERROR, "单位不存在");
            }
            if (CommonDbConst.DB_DELETE_LOGICAL.equals(unitDomainOne.getStatus())) {
                return new ResDto(Const.SERVER_ERROR, "单位已删除");
            }
        }
        ApiUnitDto apiUnitDto = BeanMapper.map(unitDomainOne, ApiUnitDto.class);
        String data = JsonMapper.defaultMapper().toJson(apiUnitDto);

        return new ResDto(ConstEum.SUCCESS, data);
    }

    @Override
    public ResDto deleteUnit(String id) {

        UnitDomain unitDomainOne = null;
        if (StringUtils.isNotBlank(id)) {
            unitDomainOne = unitRepository.findOne(id);
            if (unitDomainOne == null) {
                return new ResDto(Const.SERVER_ERROR, "单位不存在");
            }
        }
        List<LaboratoryDomain> laboratoryDomainList = laboratoryRepository.findAllByUnitIdAndStatus(unitDomainOne.getId(),CommonDbConst.DB_DELETE_NORMAL);
        if (!laboratoryDomainList.isEmpty()){
            return new ResDto(Const.SERVER_ERROR,"该单位存在实验室，请先删除该单位下实验室");
        }
        List<UserInfo> allUserByUnitId = userInfoRepository.findAllByUnitId(id);
        if (!allUserByUnitId.isEmpty()){
            return new ResDto(Const.SERVER_ERROR,"该院系下存在有效用户，请先删除院系下的用户");
        }


        try {
            //逻辑删除
            unitDomainOne.setStatus(CommonDbConst.DB_DELETE_LOGICAL);
            unitRepository.save(unitDomainOne);
//            unitRepository.delete(id);
            //改变（逻辑删除）用户负责表中该单位有效状态
            if (unitDomainOne.getUnitType().equals(CommonDbConst.UNIT_TYPE_YUAN)) {
                List<UserLaboratory> allByManagerUnitIdList = userLaboratoryRepository.findAllByManagerUnitIdAndType(id, CommonDbConst.USER_MANAGER_UNIT);
                for (UserLaboratory userLaboratory : allByManagerUnitIdList) {
                    userLaboratory.setStatus(CommonDbConst.DB_DELETE_LOGICAL);
                }
                userLaboratoryRepository.save(allByManagerUnitIdList);

            }



        } catch (Exception e) {
            e.printStackTrace();
            logger.error("删除单位信息异常：{}", e);
            return new ResDto(Const.SERVER_ERROR, "删除单位信息异常");
        }


        return new ResDto(Const.SUCCESS, "删除成功");
    }

    @Override
    public ResDto getUnitList(FrontPage page) {
        Integer pageSize = page.getSize();
        Integer pageNum = page.getPage();
        UnitQuery unitQuery;
        //2.Map conditionMap
        Map<String, Object> conditionMap = page.getCondition();
        if (null == conditionMap || conditionMap.isEmpty()) {
            unitQuery = new UnitQuery();
        } else {
            String conditionJson = JsonMapper.defaultMapper().toJson(conditionMap);
            ApiUnitDto dto = JsonMapper.defaultMapper().fromJson(conditionJson, ApiUnitDto.class);
            unitQuery = BeanMapper.map(dto, UnitQuery.class);
        }
        String order = "DESC";
        if (!StringUtils.isEmpty(page.getOrder())) {
            if ("ASC".equals(page.getOrder().toUpperCase())) {
                order = "ASC";
            }
        }
        String prop = "gmt_created";
        if (!StringUtils.isEmpty(page.getProp())) {
            prop = page.getProp();
        }
        //设置查询条件
        Pageable pageRequest = new PageRequest(pageNum - 1, pageSize, new Sort(Sort.Direction.fromString(order), prop));
        //状态正常
        unitQuery.setStatus(CommonDbConst.DB_DELETE_NORMAL);
        Page<UnitDomain> pageResult = mongoManager.findPage(unitQuery, pageRequest, UnitDomain.class);

        ResDto resDto = new ResDto(ConstEum.SUCCESS);
        ResDtoUtil.defaultUtil().pageDomainDtoToFrontDto(resDto, pageResult, ApiUnitDto.class, page);

        return resDto;
    }

    @Override
    public ResDto getUnitList(String unit_type,String status) {

        try {
            List<ApiUnitDto> apiUnitDtoList;
            List<UnitDomain> apiUnitDomainList;
            //查找 校级/院系
            if (StringUtils.isNotBlank(unit_type)) {
                 //单位状态
                if (CommonDbConst.DB_DELETE_NORMAL.equals(status)){
                     apiUnitDomainList = unitRepository.findAllByUnitTypeAndStatus(unit_type, CommonDbConst.DB_DELETE_NORMAL);
                }else {
                    apiUnitDomainList=unitRepository.findAllByUnitType(unit_type);
                }

            } else {
                //查找全部
                //单位状态
                if (CommonDbConst.DB_DELETE_NORMAL.equals(status)){
                    apiUnitDomainList = unitRepository.findAllByStatus(CommonDbConst.DB_DELETE_NORMAL);
                }else {
                    apiUnitDomainList = unitRepository.findAll();
                }

            }

            apiUnitDtoList = BeanMapper.mapList(apiUnitDomainList, ApiUnitDto.class);
            String data = JsonMapper.defaultMapper().toJson(apiUnitDtoList);

            return new ResDto(ConstEum.SUCCESS, data);

        } catch (Exception e) {
            e.printStackTrace();
            return new ResDto(Const.SERVER_ERROR, "获取单位信息失败");
        }


    }
}
